#include "stdio.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "app_user.h"
#include "app_mqtt.h"
#include "app_espnow.h"
#include "string.h"
#include "app_wifi.h"
#include "app_smartconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "nvs_flash.h"

static const char *TAG = "app_use";
/*
用户的通讯协议
源id 目标id  数据ID 设置用户信息 名字长度 name gender age
 01   23      45       67
                    获取数据    type
                    0x02  67位    89位

*/
esp_err_t app_user_info_save(char *message, int len)
{
    nvs_handle_t my_handle;                                           // 定义句柄
    esp_err_t err = nvs_open("user_info", NVS_READWRITE, &my_handle); // 读写模式（NVS_READWRITE）打开
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err));
        return;
    }
    int name_size = 2 * (message[8] - '0');

    char name[name_size + 1];
    strncpy(name, message + 9, name_size);
    name[name_size] = '\0'; 

    char gender[3];
    strncpy(gender, message + 9+name_size,2);
    gender[2] = '\0';

    int age = atoi(message + 11 + name_size);

    ESP_LOGI(TAG,"Name: %s\n", name);
    ESP_LOGI(TAG,"gender: %s\n", gender);
    ESP_LOGI(TAG,"Age: %d\n", age);


    nvs_set_str(my_handle, "name", name);
    nvs_set_str(my_handle, "gender", gender);
    nvs_set_i8(my_handle, "age", age);
    err = nvs_commit(my_handle);
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG,"Failed to commit updates to NVS!\n");
    }
    nvs_close(my_handle); // 关闭NVS句柄
}
void send_data_mqtt(char *name, char *gender, int age)
{
    char message[256]; 
    snESP_LOGI(TAG,message, sizeof(message), "病人姓名：%s,病人性别：%s,病人年龄：%d", name, gender, age);
    size_t len = strlen(message);
    app_mqtt_send(message, len);
}
void send_data_espnow(char *name, char *gender, char *age)
{
    char message[256]; 
    snESP_LOGI(TAG,message, sizeof(message), "病人姓名：%s,病人性别：%s,病人年龄：%d", name, gender, age);
    size_t len = strlen(message);
    app_espnow_send(message, len);
}

esp_err_t app_user_info_send(char *message)
{
    nvs_handle_t my_handle;                                           // 定义句柄
    esp_err_t err = nvs_open("user_info", NVS_READWRITE, &my_handle); // 读写模式（NVS_READWRITE）打开
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err));
        return;
    }

    size_t name_size;
    err = nvs_get_str(my_handle, "name", NULL, &name_size);
    char *name = malloc(name_size);
    nvs_get_str(my_handle, "name", name, &name_size);

    size_t gender_size;
    err = nvs_get_str(my_handle, "gender", NULL, &gender_size);
    char *gender = malloc(gender_size);
    nvs_get_str(my_handle, "gender", gender, &gender_size);

    int age = nvs_get_i8(my_handle, "age", NULL);

    char data_id = {message[8], message[9], '\0'};
    unsigned char id = (unsigned char)strtol(data_id, NULL, 16);
    switch (id)
    {
    case 0x01: // espnow返回
        send_data_espnow(name, gender, age);
        break;
    case 0x02: // mqtt返回
        send_data_mqtt(name, gender, age);
        break;
    case 0xff: // all
        send_data_espnow(name, gender, age);
        send_data_mqtt(name, gender, age);
        break;
    default:
        ESP_LOGI(TAG,"error");
        break;
    }
}

void app_user_message_handler(char *message, int len)
{
    char data_id = {message[6], message[7], '\0'};
    unsigned char id = (unsigned char)strtol(data_id, NULL, 16);
    switch (id)
    {
    case 0x01: // 设置用户信息
        // name   gender  age
        esp_err_t err = app_user_info_save(message, len);
        if (err == ESP_OK)
        {
            ESP_LOGI(TAG,"sussess");
        }
        break;

    case 0x02: // 获取用户信息
        esp_err_t err = app_user_info_send(message);
        if (err == ESP_OK)
        {
            ESP_LOGI(TAG,"sussess");
        }
        break;
    }
}

/*
配置wifi信息
源id 目标id  数据ID 设置wifi信息 id长度  ssid  密码长度  passwd
 01   23      45       67         8
                    配置模块ID    id
                    0x02  67位    89位

*/
esp_err_t app_wifi_info(char *message, int len)
{
    nvs_handle_t my_handle;                                           // 定义句柄
    esp_err_t err = nvs_open("wifi_info", NVS_READWRITE, &my_handle); // 读写模式（NVS_READWRITE）打开
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err));
        return;
    }

    int ssid_size = message[8] - '0';
    char ssid[ssid_size + 1];
    strncpy(ssid, message + 9, ssid_size);
    ssid[ssid_size] = '\0'; 

    int password_size = message[8 + ssid_size] - '0';
    char password[password_size + 1];
    strncpy(password, message + 10 + ssid_size, password_size);
    password[password_size] = '\0';

    nvs_set_str(my_handle, "ssid", ssid);
    nvs_set_str(my_handle, "password", password);

    err = nvs_commit(my_handle);
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG,"Failed to commit updates to NVS!\n");
    }
    nvs_close(my_handle); // 关闭NVS句柄
}

esp_err_t app_wifi_set_id(char *message)
{
    nvs_handle_t my_handle;                                           // 定义句柄
    esp_err_t err = nvs_open("wifi_info", NVS_READWRITE, &my_handle); // 读写模式（NVS_READWRITE）打开
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err));
        return;
    }
    char wifi_id = {message[8], message[9], '\0'};

    nvs_set_str(my_handle, "id", wifi_id);
    err = nvs_commit(my_handle);
    if (err != ESP_OK)
    {
        ESP_LOGI(TAG,"Failed to commit updates to NVS!\n");
    }
    nvs_close(my_handle); // 关闭NVS句柄
}
void app_wifi_message_handler(char *message, int len)
{
    char data_id = {message[6], message[7], '\0'};
    unsigned char id = (unsigned char)strtol(data_id, NULL, 16);
    switch (id)
    {
    case 0x01: // 配置wifi信息
        esp_err_t err = app_wifi_info(message, len);
        if (err == ESP_OK)
        {
            ESP_LOGI(TAG,"sussess");
        }
        break;

    case 0x02: // 配置模块ID
        esp_err_t err = app_wifi_set_id(message);
        if (err == ESP_OK)
        {
            ESP_LOGI(TAG,"sussess");
        }
        break;
    default:
        ESP_LOGI(TAG,"error");
        break;
    }
}
